package com.nowcoder.community.controller;

import com.nowcoder.community.annotation.LoginRequired;
import com.nowcoder.community.entity.Message;
import com.nowcoder.community.entity.Page;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.MessageService;
import com.nowcoder.community.service.UserService;
import com.nowcoder.community.utils.CommunityUtils;
import com.nowcoder.community.utils.HostHolder;
import com.nowcoder.community.utils.SensitiveWordFilter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;

import java.util.*;

/*
* 消息 - 私信
* */
@Controller
@RequestMapping("/letter")
public class LetterController {

    @Autowired
    private MessageService messageService;
    @Autowired
    private UserService userService;

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private SensitiveWordFilter sensitiveWordFilter;

    @GetMapping("/list")
    @LoginRequired
    public String getLetterPage(Page page, Model model){
        User user = hostHolder.getUser();
        page.setLimit(5);
        page.setRows(messageService.countConversations(user.getId()));

        int unreadLetterCount = messageService.countUnreadMessages(user.getId());
        int unreadNoticeCount = messageService.countUnreadNotices(user.getId(), null);
        List<Message> messages = messageService.findConversations(user.getId(), page.getOffset(), page.getLimit());
        List<Map<String, Object>> conversations = new LinkedList<>();
        for (Message message:messages){
            HashMap<String, Object> map = new HashMap<>();
            int friendId = user.getId() != message.getFromId() ? message.getFromId() : message.getToId();
            map.put("friend", userService.findUserById(friendId));
            map.put("message", message);
            map.put("unreadCount", messageService.countConversationUnreadMessages(user.getId(), message.getConversationId()));
            map.put("messageCount", messageService.countConversationMessages(message.getConversationId()));
            conversations.add(map);
        }
        model.addAttribute("unreadLetterCount", unreadLetterCount);
        model.addAttribute("unreadNoticeCount", unreadNoticeCount);
        model.addAttribute("conversations", conversations);
        return "/site/letter";
    }

    @GetMapping("/detail/{friendId}")
    @LoginRequired
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public String getLetterDetailPage(@PathVariable int friendId, Page page, Model model){
        User me = hostHolder.getUser();
        User friend = userService.findUserById(friendId);
        String conversationId = makeConversationId(me.getId(), friendId);
        page.setRows(messageService.countConversationMessages(conversationId));
        page.setLimit(5);
        page.setPath("/letter/detail/" + friendId);

        List<Message> messages = messageService.findConversationMessages(conversationId, page.getOffset(), page.getLimit());
        List<Map<String, Object>> messagesVO = new LinkedList<>();
        ArrayList<Integer> ids = new ArrayList<>();
        for (Message message: messages){
            HashMap<String, Object> map = new HashMap<>();
            map.put("message",message);
            map.put("fromUser", userService.findUserById(message.getFromId()));
            messagesVO.add(map);
            if (message.getStatus() == 0 && message.getToId() == me.getId())
                ids.add(message.getId());
        }
        model.addAttribute("friend", friend);
        model.addAttribute("messages", messagesVO);
        if (!ids.isEmpty())
            messageService.updateMessagesStatus(ids, 1);
        return "/site/letter-detail";
    }

    @PostMapping("/add")
    @ResponseBody
    @LoginRequired
    public String addMessage(String content, String toUsername){
        if (StringUtils.isBlank(toUsername))
            return CommunityUtils.getJsonString(400, "目标用户不能为空");

        if (StringUtils.isBlank(content))
            return CommunityUtils.getJsonString(400, "私信内容不能为空");

        User toUser = userService.findUserByUsername(toUsername);
        if (toUser == null)
            return CommunityUtils.getJsonString(400, "目标用户不存在");

        Message message = new Message();
        message.setContent(sensitiveWordFilter.filter(HtmlUtils.htmlEscape(content)));
        message.setFromId(hostHolder.getUser().getId());
        message.setToId(toUser.getId());
        message.setConversationId(makeConversationId(message.getFromId(), message.getToId()));
        message.setStatus(0);
        message.setCreateTime(new Date());
        messageService.addMessage(message);
        return CommunityUtils.getJsonString(200, "发送成功");
    }

    @PostMapping("/delete")
    @ResponseBody
    @LoginRequired
    public String deleteMessage(int messageId){
        Message message = messageService.findMessageById(messageId);
        if (message == null || message.getStatus() == 2){
            return CommunityUtils.getJsonString(404, "您删除的消息不存在");
        }

        if (message.getFromId() != hostHolder.getUser().getId()){
            return CommunityUtils.getJsonString(403, "您没有权限删除该消息");
        }

        messageService.updateMessagesStatus(Arrays.asList(messageId), 2);
        return CommunityUtils.getJsonString(200, "删除消息成功");
    }

    private String makeConversationId(int fromId, int toId){
        return fromId < toId ? fromId + "_" + toId : toId + "_" + fromId;
    }
}
